import React, { useState, useEffect, useRef } from 'react';
import { LeftSquareOutlined, RightSquareOutlined } from '@ant-design/icons';
import 'antd/dist/antd.less';
import { createBrowserHistory } from 'history';
import './Carousel.less';

// *-------------------------------------
export default function Carousel({ children, autoplay = false }) {
  // console.log(autoplay);
  // todo 这是图片的数组
  const img = children
    ? children?.map((item) => {
        return item.props.src;
      })
    : [
        'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201607%2F31%2F20160731205337_2x4Hf.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1637737235&t=6bc223b05bbf8697418d1b76852ea7ac',
      ];
  // todo 这是锚点标签的长度
  const anchorLength = (img.length - 1) * 20 + img.length * 45 + 40;
  // todo 这是所有图片盒子的长度
  const superBox = (img.length + 2) * 100;
  // todo 这是一个图片的长度的百分比
  const imgLength = 100 / (img.length + 2);
  // todo 这是锚点数据
  const [imgIndex, setImgIndex] = useState(0);
  //*----------------------------------------------------------------------------
  //todo----------------------------------------------------------------------------
  // todo 这是图片滑动的数据
  const [moveSuperBox, setMoveSuperBox] = useState(1);
  const moveSuperBoxRef = useRef(1);
  const [moveFlag, setMoveFlag] = useState(true);
  const container = useRef(null);
  // todo 每次数据更新 useEffect 调用的函数
  const setTransition = () => {
    // todo 每次图片滑动完成进行的回调函数 判断是否为前后假图片
    function transitionend() {
      container.current.style.transitionProperty = 'none';
      if (moveSuperBoxRef.current === 0) {
        // todo 定时器防止图片还没滑完就瞬间切换
        setTimeout(() => {
          setMoveSuperBox(img.length);
          moveSuperBoxRef.current = img.length;
        }, 0);
      }
      if (moveSuperBoxRef.current === img.length + 1) {
        // todo 定时器防止图片还没滑完就瞬间切换
        setTimeout(() => {
          setMoveSuperBox(1);
          moveSuperBoxRef.current = 1;
        }, 0);
      }
      container.current.removeEventListener('transitionend', transitionend, false);
      // todo 这是执行完判断才放开可以点击后执行 handleChange 后的代码
      // todo 相当于防抖
      setMoveFlag(true);
    }
    container.current.addEventListener('transitionend', transitionend, false);
    // todo 这是控制图片移动位置的
    container.current.style.transform = `translateX(${-moveSuperBoxRef.current * imgLength}%)`;
  };
  // todo 所有的change的函数
  const handleChange = (num) => {
    // todo 这是执行完判断才放开可以点击后执行 handleChange 后的代码
    // todo 相当于防抖
    //if (!moveFlag) return;
    container.current.style.transitionProperty = 'all';
    setMoveFlag(false);
    // todo set 还是负责触发 useEffect
    setMoveSuperBox(num[0]);
    // todo Ref 来控制真数据
    moveSuperBoxRef.current = num[0];
    // todo 控制锚点的数据
    const a = num[0] === 0 ? img.length - 1 : num[0] - 1;
    const b = num[0] === img.length + 1 ? 0 : num[0] - 1;
    setImgIndex(num[1] === 1 ? a : b);
  };
  // todo 负责页面进入初始和数据更新
  const timer = useRef(null);
  const play = () => {
    timer.current = setTimeout(() => {
      console.log(123131321);
      carouselRight();
    }, 1500);
  };

  const pausePlay = () => {
    if (autoplay) {
      clearTimeout(timer.current);
      timer.current = null;
    }
  };

  const startPlay = () => {
    autoplay && play();
  };

  useEffect(() => {
    setTransition();
    if (autoplay) {
      play();
    }
    return () => {
      if (autoplay) {
        pausePlay();
      }
    };
  }, [moveSuperBox]);

  //todo----------------------------------------------------------------------------
  //*----------------------------------------------------------------------------
  // todo 这是左的点击事件
  const carouselLeft = () => {
    // todo 这里判断的 0 ? img.length 是不会走到的
    // todo 可以写 handleChange(false ? 99999 : moveSuperBox - 1);
    // todo 右按钮只要控制图片向前滑动就行了
    // handleChange(moveSuperBox === 0 ? img.length : [moveSuperBox - 1, 1]);
    // todo 因为定时器会重新刷新页面 所以 useState 定义变量就无意义了 改用 Ref 定义变量
    handleChange(moveSuperBoxRef.current === 0 ? img.length : [moveSuperBoxRef.current - 1, 1]);
  };
  // todo 这是右的点击事件
  const carouselRight = () => {
    // todo 这里判断的 img.length + 1 ? 0 是不会走到的
    // todo 可以写 handleChange(false ? 99999 : moveSuperBox + 1);
    // todo 右按钮只要控制图片向后滑动就行了
    // handleChange(moveSuperBox === img.length + 1 ? 0 : [moveSuperBox + 1, 2]);
    // todo 因为定时器会重新刷新页面 所以 useState 定义变量就无意义了 改用 Ref 定义变量
    handleChange(moveSuperBoxRef.current === img.length + 1 ? 0 : [moveSuperBoxRef.current + 1, 2]);
  };

  // todo 这是定义的锚点点击事件
  const anchorPoint = (index) => {
    // todo 直接调用 change 函数
    handleChange([index + 1, 2]);
  };

  // ! 这是虚拟 DOM
  return (
    <div className="contentBox">
      {/* 轮播图内容 */}
      <div className="carousel" onMouseEnter={pausePlay} onMouseLeave={startPlay}>
        {/* 轮播图图片 */}
        <div
          ref={container}
          className="superBox"
          style={{
            width: `${superBox}%`,
            transform: `translateX(${moveSuperBox}%)`,
            transition: `all 0.7s ease-out`,
          }}
        >
          <div className="carouselContent" style={{ width: `${imgLength}%` }}>
            <img src={img?.[img.length - 1]} />
          </div>
          {img.map((item, index) => {
            return (
              <div key={index} className="carouselContent" style={{ width: `${imgLength}%` }}>
                <img src={item} />
              </div>
            );
          })}
          <div className="carouselContent" style={{ width: `${imgLength}%` }}>
            <img src={img?.[0]} />
          </div>
        </div>
        {/* 轮播图图片 结束*/}

        {/* 轮播图按钮 */}
        <div className="carouselLeft" onClick={carouselLeft}>
          <LeftSquareOutlined className="icon" />
        </div>
        <div className="carouselRight" onClick={carouselRight}>
          <RightSquareOutlined className="icon" />
        </div>
        {/* 轮播图按钮 结束*/}

        {/* 轮播图锚点 */}
        <div className="carouselAnchorPoint" style={{ width: `${anchorLength}px` }}>
          {img.map((item, index) => {
            return (
              <div
                key={index}
                className={
                  index == imgIndex ? 'carouselAnchorPointLiChange' : 'carouselAnchorPointLi'
                }
                onClick={() => {
                  anchorPoint(index);
                }}
              >
                <div
                  className={
                    index == imgIndex
                      ? '.carouselAnchorPointLiSonChange'
                      : 'carouselAnchorPointLiSon'
                  }
                ></div>
              </div>
            );
          })}
        </div>
        {/* 轮播图锚点 结束*/}
      </div>
      {/* 轮播图内容  结束*/}
    </div>
  );
}
